# 控制器层
# 引入 渲染工具，重定向方法，对象获取器
from django.shortcuts import render, redirect, get_object_or_404
# 获取登录装饰器
from django.contrib.auth.decorators import login_required
# 获取分页工具
from django.core.paginator import Paginator
# 该插件负责生成动态路由
from django.urls import reverse
# 引入商品相关的模型
from .models import Goods, Category, Comment
# 引入商品相关的表单
from .forms import GoodsForm,  CommentForm
from .models import Goods, Category, Comment, GoodsImage  # 关键：添加 GoodsImage

# 定义方法商品列表
def goods_list(request):
    """商品列表页，支持分页"""
    # 查询数据库，获取所有的商品，此时不会执行数据库查询
    goods_list = Goods.objects.all()
    # 对商品进行分页
    paginator = Paginator(goods_list, 10)  # 每页显示10个商品
    # 获取当前页
    page_number = request.GET.get('page')
    # 分页器才会真的执行数据库查询
    page_obj = paginator.get_page(page_number)
    # 渲染页面 ，这里渲染页面的时候，必须传递请求上下文，否则无法获取登录信息cookie，session等
    return render(request, 'goods/goods_list.html', {
        'page_obj': page_obj,
        # 这里依然不会执行查询，前端循环渲染的时候才会查询
        'categories': Category.objects.all()
    })

# 商品详情页，传递的参数，请求上下文，商品id
def goods_detail(request, pk):
    """商品详情页"""
    # 使用助手函数查询商品，如果不存在则返回404
    goods = get_object_or_404(Goods, pk=pk)
    # 加载商品的所有评论
    comments = goods.comments.all()

    # 如果是post方法，那么就是提交评论
    if request.method == 'POST':
        # 提取post请求参数，然后装载到评论模型表单中
        comment_form = CommentForm(request.POST)
        # todo 这里在laravel中也有类似的写法，但是记不起来了，希望某一天看到的时候补全对应的代码
        if comment_form.is_valid() and request.user.is_authenticated:
            comment = comment_form.save(commit=False)
            comment.goods = goods
            comment.user = request.user
            comment.save()
            return redirect('goods:detail', pk=goods.pk)
    else:
        comment_form = CommentForm()

    return render(request, 'goods/goods_detail.html', {
        'goods': goods,
        'comments': comments,
        'comment_form': comment_form
    })

@login_required
def add_goods(request):
    """添加商品"""
    if request.method == 'POST':
        goods_form = GoodsForm(request.POST, request.FILES)

        if goods_form.is_valid():
            # 此时只是提交到内存，并没有写入到硬盘，这个操作是可以在正式写入硬盘之前可以修改数据，减少了磁盘刷新的次数，减少磁盘IO的次数
            goods = goods_form.save(commit=False)
            # 将数据写入到硬盘
            goods.save()
            goods_form.save_m2m()  # 保存多对多关系 强制强关联数据写入到硬盘

            # 处理详情图片
            for image in request.FILES.getlist('detail_images'):
                # 这里模型会根据字段定义的保存路径自动上传图片
                GoodsImage.objects.create(image=image, goods=goods)
            # 重定向 语法：路由，参数
            return redirect('goods:detail', pk=goods.pk)
    else:
        goods_form = GoodsForm()

    return render(request, 'goods/add_goods.html', {
        'goods_form': goods_form,
        'categories': Category.objects.all()
    })
